#include <utility>
#include <limits>
#include "ZDataBase.h"
#include "ZDataFrame.h"

#include <iostream>
#include <unordered_set>
#include "ZDataView.h"



template<typename StringType>
NDFrame::ZDataFrame<StringType> &NDFrame::ZDataFrame<StringType>::operator=(const ZDataFrame &other) {
    if (this == &other) { return *this;}

    size_t old_size = this->m_size;
    size_t old_capacity = this->m_capacity;
    auto old_ptr = std::move(ItemPtr);

    try {
        this->m_size = other.m_size;
        this->m_capacity = other.m_capacity;
        allocate(this->m_capacity);
        auto thisPtr = ItemPtr.get();
        const auto& otherPtr = other.getItemPtr();

        for (size_t i = 0; i < other.m_size; ++i) {
            thisPtr[i] = otherPtr[i];
        }
    } catch (...) {
        std::cout << "ZDataFrame<StringType>::operator=: "
               << "Error occurred during assignment. "
               << "Reverting to previous state." << std::endl;
        ItemPtr = std::move(old_ptr);
        this->m_size = old_size;
        this->m_capacity = old_capacity;
        throw;
    }

    return *this;
}


template<typename StringType>
NDFrame::ZDataFrame<StringType> &NDFrame::ZDataFrame<StringType>::operator=(ZDataFrame &&other) noexcept {
    if (this == &other) {
        return *this;
    }

    this->m_size = other.m_size;
    this->m_capacity = other.m_capacity;
    this->ItemPtr = std::move(other.ItemPtr);

    other.m_size = 0;
    other.m_capacity = 0;

    return *this;
}



template<typename StringType>
void NDFrame::ZDataFrame<StringType>::reserve(size_t new_capacity) {
    std::shared_ptr<ItemType[]> new_ptr = std::shared_ptr<ItemType[]>(new ItemType[new_capacity],
                                                                      std::default_delete<ItemType[]>());
    std::copy(this->ItemPtr.get(), this->ItemPtr.get() + this->m_size, new_ptr.get());
    this->ItemPtr = new_ptr;
    this->m_capacity = new_capacity;
}



//////////////////////////////////////////////////////////////////////////////
////					  对应字段值： 对df.txt 进行行合并
//////////////////////////////////////////////////////////////////////////////
template<typename StringType>
NDFrame::ZDataFrame<StringType>
NDFrame::ZDataFrame<StringType>::DF_merge_line(int width, int height, StringType &&sep) {
    if (this->m_size < 2) {
        return *this;
    }

    ZDataFrame mergedFrame(*this);

    size_t i = 0;
    while (i < mergedFrame.m_size - 1) {
        ItemType &current = mergedFrame.ItemPtr.get()[i];
        ItemType &next = mergedFrame.ItemPtr.get()[i + 1];

        if (std::abs(next.x0 - current.x1) < width && std::abs(next.y0 - current.y0) < height) {
            current.text += sep + next.text;
            current.x0 = std::min(current.x0, next.x0);
            current.y0 = std::min(current.y0, next.y0);
            current.x1 = std::max(current.x1, next.x1);
            current.y1 = std::max(current.y1, next.y1);
            current.width = current.x1 - current.x0;
            current.height = std::max(current.height, next.height);

            for (size_t j = i + 1; j < mergedFrame.m_size - 1; ++j) {
                mergedFrame.ItemPtr.get()[j] = mergedFrame.ItemPtr.get()[j + 1];
            }
            --mergedFrame.m_size;
        } else {
            ++i;
        }
    }
    return mergedFrame;
}


template<typename StringType>
void NDFrame::ZDataFrame<StringType>::reset_index() {
    if (this->empty()) {
        return;
    }
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        thisPtr[i].idx = static_cast<int>(i);
    }
}


template<typename StringType>
NDFrame::ZDataFrame<StringType> NDFrame::ZDataFrame<StringType>::DF_pointers_to_df(const VecItemPtr &pointers) const {
    if (pointers.empty()) {
        throw std::out_of_range("pointers is empty");
    }

    std::unordered_set<ItemType *> pointers_set(pointers.begin(), pointers.end());
    const size_t valid_pointer_count = pointers_set.size();

    ZDataFrame newFrame(valid_pointer_count);
    const auto newPtr = newFrame.getItemPtr();
    const auto thisPtr = this->ItemPtr.get();

    size_t j = 0;
    for (size_t i = 0; i < m_size && j < valid_pointer_count; ++i) {
        if (pointers_set.find(&thisPtr[i]) != pointers_set.end()) {
            newPtr[j] = thisPtr[i];
            newPtr[j].idx = static_cast<int>(j);
            j++;
        }
    }
    newFrame.m_size = j;
    return newFrame;
}


//////////////////////////////////////////////////////////////////////////////
////					  删除函数
//////////////////////////////////////////////////////////////////////////////
template<typename StringType>
NDFrame::ZDataFrame<StringType> NDFrame::ZDataFrame<StringType>::DF_drop_pointer(const VecItemPtr &pointers) const {
    std::unordered_set<ItemType*> valid_drop_set;
    const auto thisPtr = ItemPtr.get();

    for (auto* ptr : pointers) {
        if (ptr >= thisPtr && ptr < thisPtr + m_size) {
            valid_drop_set.insert(ptr);
        }
    }

    const size_t actual_drop_count = valid_drop_set.size();
    const size_t new_size = m_size - actual_drop_count;

    ZDataFrame newFrame(new_size);
    const auto newPtr = newFrame.getItemPtr();

    size_t j = 0;
    for (size_t i = 0; i < m_size; ++i) {
        if (valid_drop_set.find(&thisPtr[i]) == valid_drop_set.end()) {
            newPtr[j] = thisPtr[i];
            newPtr[j].idx = static_cast<int>(j);
            j++;
        }
    }

    newFrame.m_size = new_size;
    return newFrame;
}


template<typename StringType>
template<typename T>
T NDFrame::ZDataFrame<StringType>::ix_impl(const std::tuple<int, int>& indices) const {
    int row = std::get<0>(indices);
    int col = std::get<1>(indices);

    if (this->empty() || row >= this->size() || col >= 9) {
        throw std::out_of_range("Index out of range");
    }
    return std::get<col>(this->ItemPtr.get()[row].values());
}


template<typename StringType>
void NDFrame::ZDataFrame<StringType>::drop_indice_inplace(const std::vector<size_t> &indices) {
    std::vector<size_t> sorted_indices = indices;
    std::sort(sorted_indices.begin(), sorted_indices.end());

    size_t new_size = this->m_size - sorted_indices.size();
    size_t current_index = 0;

    for (size_t i = 0; i < this->m_size; ++i) {
        if (current_index < sorted_indices.size() && i == sorted_indices[current_index]) {
            ++current_index;
        } else {
            this->ItemPtr[i - current_index] = this->ItemPtr[i];
        }
    }

    this->m_size = new_size;
}


template<typename StringType>
NDFrame::ZDataFrame<StringType>
NDFrame::ZDataFrame<StringType>::drop_indice_copy(const std::vector<size_t> &indices) const {
    std::vector<size_t> sorted_indices = indices;
    std::sort(sorted_indices.begin(), sorted_indices.end());

    ZDataFrame new_frame(this->m_capacity);
    new_frame.m_size = this->m_size - sorted_indices.size();

    size_t current_index = 0;
    for (size_t i = 0; i < this->m_size; ++i) {
        if (current_index < sorted_indices.size() && i == sorted_indices[current_index]) {
            ++current_index;
        } else {
            new_frame.ItemPtr[i - current_index] = this->ItemPtr[i];
        }
    }

    return new_frame;
}


template<typename StringType>
template<NDFrame::Field field, typename Comparator>
constexpr auto NDFrame::ZDataFrame<StringType>::getCompare() {
    if constexpr (field == Field::IDX) {
        return [](const ItemType& a, const ItemType& b) { return Comparator()(a.idx, b.idx); };
    } else if constexpr (field == Field::X0) {
        return [](const ItemType& a, const ItemType& b) { return Comparator()(a.x0, b.x0); };
    } else if constexpr (field == Field::Y0) {
        return [](const ItemType& a, const ItemType& b) { return Comparator()(a.y0, b.y0); };
    } else if constexpr (field == Field::X1) {
        return [](const ItemType& a, const ItemType& b) { return Comparator()(a.x1, b.x1); };
    } else if constexpr (field == Field::Y1) {
        return [](const ItemType& a, const ItemType& b) { return Comparator()(a.y1, b.y1); };
    } else if constexpr (field == Field::WIDTH) {
        return [](const ItemType& a, const ItemType& b) { return Comparator()(a.width, b.width); };
    } else if constexpr (field == Field::HEIGHT) {
        return [](const ItemType& a, const ItemType& b) { return Comparator()(a.height, b.height); };
    } else {
        static_assert(always_false<field>::value, "Invalid field name for sorting");
        return [](const ItemType&, const ItemType&) { return false; };
    }
}


template<typename StringType>
template<NDFrame::Field field, typename T>
constexpr auto NDFrame::ZDataFrame<StringType>::getFieldAll(const DataItem<StringType>& item) -> const T& {
    if constexpr (field == Field::IDX) {
        return item.idx;
    } else if constexpr (field == Field::X0) {
        return item.x0;
    } else if constexpr (field == Field::Y0) {
        return item.y0;
    } else if constexpr (field == Field::X1) {
        return item.x1;
    } else if constexpr (field == Field::Y1) {
        return item.y1;
    } else if constexpr (field == Field::WIDTH) {
        return item.width;
    } else if constexpr (field == Field::HEIGHT) {
        return item.height;
    } else if constexpr (field == Field::TEXT) {
        return item.text;
    } else if constexpr (field == Field::TEXT_SEP) {
        return item.text_sep;
    } else {
        static_assert(always_false<field>::value, "Invalid field name for sorting");
        return 0;
    }
}


template<typename StringType>
template<NDFrame::Field field>
constexpr auto NDFrame::ZDataFrame<StringType>::getFieldRef(DataItem<StringType>& item) -> int& {
    if constexpr (field == Field::IDX) {
        return item.idx;
    } else if constexpr (field == Field::X0) {
        return item.x0;
    } else if constexpr (field == Field::Y0) {
        return item.y0;
    } else if constexpr (field == Field::X1) {
        return item.x1;
    } else if constexpr (field == Field::Y1) {
        return item.y1;
    } else if constexpr (field == Field::WIDTH) {
        return item.width;
    } else if constexpr (field == Field::HEIGHT) {
        return item.height;
    } else {
        static_assert(always_false<field>::value, "Invalid field name for accessing integer field by reference");
        return item.idx;
    }
}


template<typename StringType>
template<NDFrame::Field field>
constexpr auto NDFrame::ZDataFrame<StringType>::getFieldInt(const DataItem<StringType>& item) -> int {
    if constexpr (field == Field::IDX) {
        return item.idx;
    } else if constexpr (field == Field::X0) {
        return item.x0;
    } else if constexpr (field == Field::Y0) {
        return item.y0;
    } else if constexpr (field == Field::X1) {
        return item.x1;
    } else if constexpr (field == Field::Y1) {
        return item.y1;
    } else if constexpr (field == Field::WIDTH) {
        return item.width;
    } else if constexpr (field == Field::HEIGHT) {
        return item.height;
    } else {
        static_assert(always_false<field>::value, "Invalid field name for sorting");
        return 0;
    }
}



template<typename StringType>
template<NDFrame::Field field>
void NDFrame::ZDataFrame<StringType>::sort(const bool descending) {
    if (this->empty()) {
        throw std::runtime_error("Cannot sort an empty column.");
    }

    const auto& thisPtr = ItemPtr.get();
    std::vector<ItemType*> items(m_size);
    for (size_t i = 0; i < m_size; ++i) {
        items[i] = &thisPtr[i];
    }

    if (descending) {
        std::sort(items.begin(), items.end(),
            [](const ItemType* a, const ItemType* b) {
                return getCompare<field, std::greater<>>()(*a, *b);
            });
    }
    else {
        std::sort(items.begin(), items.end(),
            [](const ItemType* a, const ItemType* b) {
                return getCompare<field, std::less<>>()(*a, *b);
            });
    }

    // 原地重排列数据
    for (size_t i = 0; i < m_size; ++i) {
        size_t j = i;
        while (items[j] != &thisPtr[j]) {
            size_t target = items[j] - thisPtr;
            std::swap(thisPtr[j], thisPtr[target]);
            std::swap(items[j], items[target]);
            items[j] = &thisPtr[j];
        }
    }

    for (size_t i = 0; i < m_size; ++i) {
        thisPtr[i].idx = static_cast<int>(i);
    }
}


template<typename StringType>
template<NDFrame::Field field>
void NDFrame::ZDataFrame<StringType>::sub(const int num) {
    if (empty()) return;
    auto& thisPtr = ItemPtr.get();
    for (size_t i = 0; i < this->size(); ++i) {
        int& field_ = getFieldRef<field>(thisPtr[i]);
        field_ -= num;
        if (field_ < 0) {
            field_ = 0;
        }
    }
}


template<typename StringType>
template<NDFrame::Field field>
void NDFrame::ZDataFrame<StringType>::add(const int num, const int max_num) {
    if (empty()) return;
    auto& thisPtr = ItemPtr.get();
    for (size_t i = 0; i < m_size; ++i) {
        int& field_ = getFieldRef<field>(thisPtr[i]);
        field_ += num;
        if (field_ > max_num) {
            field_ = max_num;
        }
    }
}


template<typename StringType>
template<NDFrame::Field field>
float NDFrame::ZDataFrame<StringType>::mean_col() const {
    float num_mean = 0.0f;
    if (empty()) {
        return num_mean;
    }
    const auto& thisPtr = ItemPtr.get();
    for (size_t i = 0; i < m_size; ++i) {
        num_mean += static_cast<float>(getFieldInt<field>(thisPtr[i]));
    }
    return num_mean / m_size;
}


template<typename StringType>
template<NDFrame::Field field>
size_t NDFrame::ZDataFrame<StringType>::max_col() const {
    int max_value = std::numeric_limits<int>::min();

    const auto& thisPtr = ItemPtr.get();
    for (size_t i = 0; i < m_size; ++i) {
        max_value = std::max(max_value, getFieldInt<field>(thisPtr[i]));
    }
    return max_value;
}


template<typename StringType>
template<NDFrame::Field field>
size_t NDFrame::ZDataFrame<StringType>::min_col() const {
    int min_value = std::numeric_limits<int>::max();

    const auto& thisPtr = ItemPtr.get();
    for (size_t i = 0; i < m_size; ++i) {
        min_value = std::min(min_value, getFieldInt<field>(thisPtr[i]));
    }

    return min_value;
}


template<typename StringType>
template<NDFrame::Field field>
std::vector<size_t> NDFrame::ZDataFrame<StringType>::len() const {
    std::vector<size_t> lens;
    lens.reserve(m_size);
    const auto& thisPtr = ItemPtr.get();
    for (size_t i = 0; i < m_size; ++i) {
        lens.emplace_back(ThisType::template getField<field>(thisPtr[i]).size());
    }
    return lens;
}



template<typename StringType>
template<NDFrame::Field field, typename T>
std::vector<std::reference_wrapper<T>> NDFrame::ZDataFrame<StringType>::values() const {
    std::vector<std::reference_wrapper<T>> result;
    if (this->empty()) {
        return result;
    }
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < m_size; ++i) {
        result.push_back(std::ref(getFieldAll<field, T>(thisPtr[i])));
    }
    return result;
}



template<typename StringType>
void NDFrame::ZDataFrame<StringType>::drop_pointer(const VecItemPtr &pointers) {
    if (pointers.empty()) { return;}
    const auto data_start = ItemPtr.get();
    const auto data_end = data_start + m_size;
    std::unordered_set<ItemType *> valid_drop_set;
    for (auto ptr : pointers) {
        if (!ptr) continue;
        if (ptr >= data_start && ptr < data_end) {
            valid_drop_set.insert(ptr);
        }
    }

    size_t new_size = 0;
    for (size_t i = 0; i < m_size; ++i) {
        if (valid_drop_set.find(&data_start[i]) == valid_drop_set.end()) {
            data_start[new_size] = std::move(data_start[i]);
            data_start[new_size].idx = static_cast<int>(new_size);
            new_size++;
        }
    }

    for (size_t i = new_size; i < m_size; ++i) {
        data_start[i].~ItemType();
    }

    m_size = new_size;
}




//////////////////////////////////////////////////////////////////////////////
////                  对应字段值： 对df.txt df.txt_sep是否在容器内
//////////////////////////////////////////////////////////////////////////////
// API版本1：指针输出
template<typename StringType>
template<NDFrame::Field field>
bool NDFrame::ZDataFrame<StringType>::isin(const std::vector<StringType> &texts, VecItemPtr &out_ptrs) const {
    if (texts.empty()) return false;
    std::unordered_set<StringType> text_set(texts.begin(), texts.end());
    return contains_impl<field>(text_set, &out_ptrs, nullptr);
}


// API版本2：数据帧输出
template<typename StringType>
template<NDFrame::Field field>
bool NDFrame::ZDataFrame<StringType>::isin(const std::vector<StringType> &texts, ZDataFrame &out_df) const {
    if (texts.empty()) return false;
    std::unordered_set<StringType> text_set(texts.begin(), texts.end());
    return contains_impl<field>(text_set, nullptr, &out_df);
}


// API版本3：仅检查存在性
template<typename StringType>
template<NDFrame::Field field>
bool NDFrame::ZDataFrame<StringType>::contains_any(const std::vector<StringType> &texts) const {
    if (texts.empty()) return false;
    std::unordered_set<StringType> text_set(texts.begin(), texts.end());
    return contains_impl<field>(text_set, nullptr, nullptr);
}


template<typename StringType>
template<NDFrame::Field field>
bool NDFrame::ZDataFrame<StringType>::contains_impl(
    const std::unordered_set<StringType> &text_set,
    VecItemPtr *out_ptrs,
    ZDataFrame *out_df) const {
    bool found = false;
    const auto &data = ItemPtr.get();

    if (out_df) out_df->clear();
    if (out_ptrs) out_ptrs->clear();

    for (size_t i = 0; i < m_size; ++i) {
        const auto &str = ThisType::template getField<field>(data[i]);
        if (text_set.find(str) != text_set.end()) {
            found = true;
            if (out_ptrs) out_ptrs->push_back(&data[i]);
            if (out_df) out_df->add_item(data[i]);
        }
    }
    return found;
}


template<typename StringType>
NDFrame::ZDataFrame<StringType>
NDFrame::ZDataFrame<StringType>::concat(const ZDataFrame& df1, const ZDataFrame& df2) {
    const size_t total_size = df1.size() + df2.size();
    ZDataFrame result(total_size + 5);
    std::copy(df1.getItemPtr(), df1.getItemPtr() + df1.size(), result.getItemPtr());
    std::copy(df2.getItemPtr(), df2.getItemPtr() + df2.size(), result.getItemPtr() + df1.size());
    return result;
}


//////////////////////////////////////////////////////////////////////////////
////					对应字段值： 对df.txt df.txt_sep进行字符拼接
//////////////////////////////////////////////////////////////////////////////
template<typename StringType>
template<NDFrame::Field field, typename CharT>
StringType NDFrame::ZDataFrame<StringType>::join(CharT separator) const {
    static_assert(std::is_same_v<CharT, typename StringType::value_type>,
                  "CharT must be the same type as StringType::value_type");

    if (this->empty()) {
        return StringType();
    }

    const auto& thisPtr = ItemPtr.get();
    size_t totalLength = 0;

    for (size_t i = 0; i < this->m_size; ++i) {
        const auto& field_value = ThisType::template getField<field>(thisPtr[i]);
        totalLength += field_value.size();
        if (i < this->m_size - 1) {
            totalLength += 1;
        }
    }

    StringType result;
    result.reserve(totalLength);
    for (size_t i = 0; i < this->m_size; ++i) {
        const auto& field_value = ThisType::template getField<field>(thisPtr[i]);
        if (i > 0) {
            result.push_back(separator);
        }
        result.append(field_value);
    }
    return result;
}



template<typename StringType>
template<NDFrame::Field field, typename CharT>
StringType NDFrame::ZDataFrame<StringType>::join_replace(CharT oldChar, const StringType& newChar) const {
    static_assert(std::is_same_v<CharT, typename StringType::value_type>, "CharT must be the same type as CharType");
    if (this->empty() || static_cast<int>(this->size()) < 2 || newChar.size() >= 2) {
        return {};
    }

    const auto& thisPtr = ItemPtr.get();
    std::basic_ostringstream<CharType> oss;
    for (size_t i = 0; i < this->m_size; ++i) {
        for (auto c: ThisType::template getField<field>(thisPtr[i])) {
            if (c == oldChar && !newChar.empty()) {
                oss << newChar.c_str();
            } else {
                oss << c;
            }
        }
    }
    return oss.str();
}


template<typename StringType>
template<NDFrame::Field field, typename CharT>
StringType NDFrame::ZDataFrame<StringType>::join_replace(CharT oldChar, CharT newChar,
                                                         const StringType &Char_) const {
    static_assert(std::is_same_v<CharT, typename StringType::value_type>, "CharT must be the same type as CharType");

    if (this->empty() || Char_.size() >= 2) {
        return {};
    }
    /*    std::function<const StringType &(const ItemType &)> getField;
    if (field_ == Field::TEXT) {
        getField = [](const ItemType &item) -> const StringType & { return item.text; };
    } else if (field_ == Field::TEXT_SEP) {
        getField = [](const ItemType &item) -> const StringType & { return item.text_sep; };
    }*/

    bool replaceOldChar = newChar != typename StringType::value_type{};
    const auto& thisPtr = ItemPtr.get();

    std::basic_ostringstream<CharType> oss;
    for (size_t i = 0; i < this->m_size; ++i) {
        if (i != 0 && !Char_.empty()) {
            oss << Char_;
        }
        for (auto c: ThisType::template getField<field>(thisPtr[i])) {
            if (c == oldChar && replaceOldChar) {
                oss << newChar;
            } else {
                oss << c;
            }
        }
    }
    return oss.str();
}


template<typename StringType>
template<NDFrame::Field field, typename CharT>
StringType NDFrame::ZDataFrame<StringType>::join_replace2(CharT oldChar0,
                                                          CharT newChar0,
                                                          CharT oldChar1,
                                                          CharT newChar1,
                                                          const StringType &Char_) const {
    static_assert(std::is_same_v<CharT, typename StringType::value_type>, "CharT must be the same type as CharType");

    if (this->empty() || Char_.size() >= 2) {
        return {};
    }

    bool replaceOldChar0 = newChar0 != typename StringType::value_type{};
    bool replaceOldChar1 = newChar1 != typename StringType::value_type{};
    const auto& thisPtr = ItemPtr.get();

    std::basic_ostringstream<CharType> oss;
    for (size_t i = 0; i < this->m_size; ++i) {
        if (i != 0 && !Char_.empty()) {
            oss << Char_;
        }
        for (auto c: ThisType::template getField<field>(thisPtr[i])) {
            if (c == oldChar0 && replaceOldChar0) {
                oss << newChar0;
            } else if (c == oldChar1 && replaceOldChar1) {
                oss << newChar1;
            } else {
                oss << c;
            }
        }
    }
    return oss.str();
}


//////////////////////////////////////////////////////////////////////////////
////							对应字段值： 对df.txt df.txt_sep进行字符替换
//////////////////////////////////////////////////////////////////////////////
template<typename StringType>
template<NDFrame::Field field_src, NDFrame::Field field_dst, typename CharT>
void NDFrame::ZDataFrame<StringType>::replace(CharT oldChar, CharT newChar) {
    static_assert(std::is_same_v<CharT, typename StringType::value_type>, "CharT must be the same type as CharType");

    if (this->m_size == 0) {
        return;
    }
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        const StringType &original_text = ThisType::template getField<field_src>(thisPtr[i]);
        StringType modified_text = original_text; // 保存原始文本

        std::replace(modified_text.begin(), modified_text.end(), oldChar, newChar);

        if constexpr (field_dst == Field::TEXT_SEP) {
            ThisType::template getFieldText<Field::TEXT_SEP>(thisPtr[i]) = modified_text;
        } else if constexpr (field_dst == Field::TEXT) {
            ThisType::template getFieldText<field_src>(thisPtr[i]) = modified_text;
        }
    }
}


template<typename StringType>
template<NDFrame::Field field_src, NDFrame::Field field_dst, typename CharT>
void NDFrame::ZDataFrame<StringType>::regex_replace(const std::basic_regex<CharT>&  pattern_, const std::basic_string<CharT>& newChar) {
    static_assert(std::is_same_v<CharT, typename StringType::value_type>, "CharT must be the same type as CharType");

    if (this->m_size == 0) {
        return;
    }
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        const StringType &original_text = ThisType::template getField<field_src>(thisPtr[i]);
        StringType modified_text = original_text; // 保存原始文本

        modified_text = std::regex_replace(modified_text, pattern_, newChar);

        if constexpr (field_dst == Field::TEXT_SEP) {
            ThisType::template getFieldText<Field::TEXT_SEP>(thisPtr[i]) = modified_text;
        } else if constexpr (field_dst == Field::TEXT) {
            ThisType::template getFieldText<field_src>(thisPtr[i]) = modified_text;
        }
    }
}


template<typename StringType>
template<NDFrame::Field field, typename CharT>
void NDFrame::ZDataFrame<StringType>::regex_extract(const std::basic_regex<CharT>& pattern_) {
    static_assert(std::is_same_v<CharT, typename StringType::value_type>,
                 "CharT must be the same type as StringType::value_type");

    if (this->m_size == 0) {
        return;
    }

    std::match_results<typename StringType::const_iterator> match;
    const auto& thisPtr = ItemPtr.get();
    for (size_t i = 0; i < this->m_size; ++i) {
        StringType &text = ThisType::template getField<field>(thisPtr[i]);
        if (std::regex_search(text.cbegin(), text.cend(), match, pattern_)) {
            text = StringType(match[0].str());
        } else {
            text.clear();
        }
    }
}



template<typename StringType>
template<NDFrame::Field field, typename CharT>
NDFrame::ZDataFrame<StringType>
NDFrame::ZDataFrame<StringType>::DF_regex_extract(const std::basic_regex<CharT>& pattern_) {
    static_assert(std::is_same_v<CharT, typename StringType::value_type>,
                 "CharT must be the same type as StringType::value_type");
    ZDataFrame result(this->m_size > 3 ? 3 : this->m_size);
    if (this->m_size == 0) {
        return result;
    }

    std::match_results<typename StringType::const_iterator> match;
    const auto& thisPtr = ItemPtr.get();
    for (size_t i = 0; i < this->m_size; ++i) {
        const StringType& text = ThisType::template getField<field>(thisPtr[i]);
        if (std::regex_search(text.cbegin(), text.cend(), match, pattern_)) {
            thisPtr[i].text = StringType(match[1].str());
            result.push_back(thisPtr[i]);
        }
    }
    return result;
}


template<typename StringType>
template<NDFrame::Field field_src, NDFrame::Field field_dst, typename CharT>
void NDFrame::ZDataFrame<StringType>::replace(CharT oldChar0,
                                              CharT newChar0,
                                              CharT oldChar1,
                                              CharT newChar1) {
    static_assert(std::is_same_v<CharT, typename StringType::value_type>, "CharT must be the same type as CharType");

    if (this->m_size == 0) {
        return;
    }

    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        const StringType &original_text = ThisType::template getField<field_src>(thisPtr[i]);
        StringType modified_text = original_text; // 保存原始文本(save original text)

        for (auto &j : modified_text) {
            if (j == oldChar0) {
                j = newChar0;
            } else if (j == oldChar1) {
                j = newChar1;
            }
        }

        if constexpr (field_dst == Field::TEXT_SEP) {
            ThisType::template getFieldText<Field::TEXT_SEP>(thisPtr[i]) = std::move(modified_text);
        } else if constexpr (field_dst == Field::TEXT) {
            ThisType::template getFieldText<field_src>(thisPtr[i]) = std::move(modified_text);
        }
    }
}



template<typename StringType>
template<NDFrame::Field field_src, NDFrame::Field field_dst, typename MapType>
void NDFrame::ZDataFrame<StringType>::multi_replace_df_text_impl(const MapType &replacements) {
    if (this->m_size == 0) {
        return;
    }
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        StringType &modified_text = ThisType::template getField<field_src>(thisPtr[i]);
        StringType original_text = modified_text; // 保存原始文本

        for (const auto &replacement : replacements) {
            const StringType &from = replacement.first;
            const StringType &to = replacement.second;
            size_t pos = 0;
            while ((pos = modified_text.find(from, pos)) != StringType::npos) {
                modified_text.replace(pos, from.length(), to);
                pos += to.length();
            }
        }

        if constexpr (field_dst == Field::TEXT_SEP) {
            ThisType::template getField<field_src>(thisPtr[i]) = original_text;
            ThisType::template getField<Field::TEXT_SEP>(thisPtr[i]) = modified_text;
        } else if constexpr (field_dst == Field::TEXT) {
            ThisType::template getField<field_src>(thisPtr[i]) = modified_text;
        }
    }
}


//////////////////////////////////////////////////////////////////////////////
////				   通用函数 对应字段值进行过滤
//////////////////////////////////////////////////////////////////////////////
template<typename StringType>
bool NDFrame::ZDataFrame<StringType>::filter(const std::function<bool(const ItemType &)> &predicate,
                                             std::vector<DataItem<StringType> *> &out_pointers) const {
    if (!out_pointers.empty()) { out_pointers.clear(); }
    out_pointers.reserve(static_cast<int>(static_cast<double>(this->size()) * 0.5) + 2);
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        if (predicate(thisPtr[i])) {
            out_pointers.push_back(&thisPtr[i]);
        }
    }
    out_pointers.shrink_to_fit();
    return !out_pointers.empty();
}


template<typename StringType>
NDFrame::ZDataFrame<StringType>
NDFrame::ZDataFrame<StringType>::DF_filter(const std::function<bool(const ItemType &)> &predicate) const {
    ZDataFrame result(this->m_size > 3 ? 3 : this->m_size);
    if (this->m_size == 0) return result;
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        if (predicate(thisPtr[i])) {
            result.push_back(thisPtr[i]);
        }
    }
    return result;

}


//////////////////////////////////////////////////////////////////////////////
////			   专用函数 对应字段值进行过滤--返回df副本（深复制）
//////////////////////////////////////////////////////////////////////////////
template<typename StringType>
template<NDFrame::Field field>
NDFrame::ZDataFrame<StringType>
NDFrame::ZDataFrame<StringType>::DF_reg_impl(const std::vector<RegexType> &regex_) const {
    ZDataFrame result(this->m_capacity > 3 ? 3 : this->m_capacity);
    if (this->m_size == 0) return result;
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        const StringType &field_value = ThisType::template getField<field>(thisPtr[i]);
        for (const auto &reg: regex_) {
            if (matches_regex(field_value, reg)) {
                result.push_back(thisPtr[i]);
                break;
            }
        }
    }

    return result;
}



template<typename StringType>
NDFrame::ZDataFrame<StringType>
NDFrame::ZDataFrame<StringType>::DF_xyxy_impl(const std::function<bool(const DataItem<StringType> &)> &condition) const {
    ZDataFrame result(this->m_capacity > 3 ? 3 : this->m_capacity);
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        if (condition(thisPtr[i])) {
            result.push_back(thisPtr[i]);
        }
    }
    return result;
}


template<typename StringType>
template<NDFrame::Field field>
NDFrame::ZDataFrame<StringType> NDFrame::ZDataFrame<StringType>::DF_reg_common4(
        const std::vector<RegexType> &regex_, const int len,
        const std::function<bool(size_t, size_t)> &compare) const {

    ZDataFrame result(this->m_capacity > 3 ? 3 : this->m_capacity);
    if (this->m_size == 0) return result;
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        const StringType &field_value = ThisType::template getField<field>(thisPtr[i]);
        if (compare(field_value.size(), len)) {
            for (const auto &reg: regex_) {
                if (matches_regex(field_value, reg)) {
                    result.push_back(thisPtr[i]);
                    break;
                }
            }
        }
    }
    return result;
}


template<typename StringType>
template<NDFrame::Field field>
NDFrame::ZDataFrame<StringType> NDFrame::ZDataFrame<StringType>::DF_strlen_impl(
    const int len,
    const std::function<bool(size_t, size_t)> &compare) const {

    ZDataFrame result(this->m_capacity > 3 ? 3 : this->m_capacity);
    if (this->m_size == 0) return result;
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        const StringType &field_value = ThisType::template getField<field>(thisPtr[i]);
        if (compare(field_value.size(), len)) {
            result.push_back(thisPtr[i]);
            break;
        }
    }
    return result;
}



template<typename StringType>
template<NDFrame::Field field>
NDFrame::ZDataFrame<StringType> NDFrame::ZDataFrame<StringType>::DF_reg_common3(
        const std::vector<RegexType> &regex_,
        const std::function<bool(const DataItem<StringType> &)> &condition
) const {

    ZDataFrame result(this->m_capacity > 3 ? 3 : this->m_capacity);
    if (this->m_size == 0) return result;
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        if (condition(thisPtr[i])) {
            const StringType &field_value = ThisType::template getField<field>(thisPtr[i]);
            for (const auto &reg: regex_) {
                if (matches_regex(field_value, reg)) {
                    result.push_back(thisPtr[i]);
                    break;
                }
            }
        }
    }
    return result;
}


//////////////////////////////////////////////////////////////////////////////
////			   专用函数 对应字段值进行过滤--返回符合条件的地址集合
//////////////////////////////////////////////////////////////////////////////
template<typename StringType>
template<NDFrame::Field field>
bool NDFrame::ZDataFrame<StringType>::ptr_reg_impl(VecItemPtr &out_ptr,
                                                   const std::vector<RegexType> &regex_) const {

    if (out_ptr.empty()) { out_ptr.reserve(3); }
    if (this->m_size == 0) return false;
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        const StringType &field_value = ThisType::template getField<field>(thisPtr[i]);
        for (const auto &reg: regex_) {
            if (matches_regex(field_value, reg)) {
                out_ptr.push_back(&thisPtr[i]);
                break;
            }
        }
    }
    return !out_ptr.empty();
}


template<typename StringType>
template<NDFrame::Field field>
bool NDFrame::ZDataFrame<StringType>::ptr_reg_all_impl(VecItemPtr &out_ptr,
                                                   const std::vector<RegexType> &regex_) const {

    if (out_ptr.empty()) { out_ptr.reserve(3); }
    if (this->m_size == 0) return false;

    const size_t all_regex_t = regex_.size();
    if (all_regex_t == 0) return false;
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        const auto& item = thisPtr[i];
        const StringType &field_value = ThisType::template getField<field>(item);

        size_t matched_count = 0;
        for (const auto& re : regex_) {
            if (matches_regex(field_value, re)) {
                ++matched_count;
            } else {
                break;
            }
        }
        if (matched_count == all_regex_t) {
            out_ptr.push_back(&item);
        }
    }
    return !out_ptr.empty();
}


template<typename StringType>
template<NDFrame::Field field>
bool NDFrame::ZDataFrame<StringType>::ptr_reg_common5(
        VecItemPtr &out_ptr,
        const std::vector<RegexType> &regex_, const int len,
        const std::function<bool(size_t, size_t)> &compare) const {

    if (out_ptr.empty()) { out_ptr.reserve(3); }
    if (this->m_size == 0) return false;
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        const StringType &field_value = ThisType::template getField<field>(thisPtr[i]);
        if (compare(field_value.size(), len)) {
            for (const auto &reg: regex_) {
                if (matches_regex(field_value, reg)) {
                    out_ptr.push_back(&thisPtr[i]);
                    break;
                }
            }
        }
    }
    return !out_ptr.empty();
}


template<typename StringType>
template<NDFrame::Field field>
bool NDFrame::ZDataFrame<StringType>::ptr_strlen_impl(
        VecItemPtr &out_ptr, const int len,
        const std::function<bool(size_t, size_t)> &compare) const {

    if (out_ptr.empty()) { out_ptr.reserve(3); }
    if (this->m_size == 0) return false;
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        const StringType &field_value = ThisType::template getField<field>(thisPtr[i]);
        if (compare(field_value.size(), len)) {
            out_ptr.push_back(&thisPtr[i]);
            break;
        }
    }
    return !out_ptr.empty();
}


template<typename StringType>
template<NDFrame::Field field>
bool NDFrame::ZDataFrame<StringType>::ptr_reg_common4(
        VecItemPtr &out_ptr,
        const std::vector<RegexType> &regex_,
        const std::function<bool(const ItemType &)> &condition
) const {

    if (out_ptr.empty()) { out_ptr.reserve(3); }
    if (this->m_size == 0) return false;
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        const StringType &field_value = ThisType::template getField<field>(thisPtr[i]);
        if (condition(thisPtr[i])) {
            for (const auto &reg: regex_) {
                if (matches_regex(field_value, reg)) {
                    out_ptr.push_back(&thisPtr[i]);
                    break;
                }
            }
        }
    }
    return !out_ptr.empty();
}


template<typename StringType>
bool NDFrame::ZDataFrame<StringType>::ptr_xyxy(VecItemPtr &out_ptr, const std::function<bool(const DataItem<StringType> &)> &condition) const {
    if (out_ptr.empty()) { out_ptr.reserve(3); }
    if (this->m_size == 0) return false;
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        if (condition(thisPtr[i])) {
            out_ptr.push_back(&thisPtr[i]);
        }
    }
    return !out_ptr.empty();
}


//////////////////////////////////////////////////////////////////////////////
////			   使用索引进行筛选
//// DF_iloc 返回副本(深复制)
//// DV_iloc 返回视图(无复制)
//////////////////////////////////////////////////////////////////////////////
template<typename StringType>
NDFrame::ZDataFrame<StringType> NDFrame::ZDataFrame<StringType>::DF_iloc(const int idx0, const int idx1) const {
    if (idx0 < 0 || idx1 >= static_cast<int>(this->m_size) || idx0 > idx1) {
        throw std::out_of_range("Index range out of bounds");
    }
    const auto& thisPtr = ItemPtr.get();

    ZDataFrame result(idx1 - idx0 + 1);
    for (int i = idx0; i < idx1; ++i) {
        result.push_back(thisPtr[i]);
    }
    return result;
}


template<typename StringType>
bool NDFrame::ZDataFrame<StringType>::iloc(VecItemPtr &out_ptr, int idx0, int idx1) const {
    if (idx0 < 0 || idx1 >= static_cast<int>(this->m_size) || idx0 > idx1) {
        std::wcout << "Index range out of bounds\n";
        return false;
    }
    if (out_ptr.empty()) { out_ptr.reserve(7); }
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        if (thisPtr[i].x0 >= idx0 && thisPtr[i].x0 < idx1) {
            out_ptr.push_back(&thisPtr[i]);
        }
    }
    return !out_ptr.empty();
}


//////////////////////////////////////////////////////////////////////////////
////		   对ZDataFrame进行首次过滤返回视图
//////////////////////////////////////////////////////////////////////////////
template<typename StringType>
template<NDFrame::Field field>
NDFrame::ZDataView<StringType>
NDFrame::ZDataFrame<StringType>::dv_reg_impl(const std::vector<RegexType> &regex_) const {

    if (this->m_size == 0) return ZDataView{*this, 0, 0};
    const auto& thisPtr = ItemPtr.get();

    size_t startIndex = this->m_size;
    size_t endIndex = 0;

    for (size_t i = 0; i < this->m_size; ++i) {
        const StringType &field_value = ThisType::template getField<field>(thisPtr[i]);
        bool matched = false;
        for (const auto &reg: regex_) {
            if (matches_regex(field_value, reg)) {
                matched = true;
                break;
            }
        }

        if (matched) {
            if (startIndex == this->m_size) {
                startIndex = i;
            }
            endIndex = i + 1;
        } else {
            if (startIndex != this->m_size && endIndex > 0) {
                return ZDataView{*this, startIndex, endIndex};
            }
            startIndex = this->m_size;
            endIndex = 0;
        }
    }

    if (startIndex != this->m_size && endIndex > 0) {
        return ZDataView{*this, startIndex, endIndex};
    }
    return ZDataView{*this, 0, 0};
}


template<typename StringType>
template<NDFrame::Field field>
NDFrame::ZDataView<StringType> NDFrame::ZDataFrame<StringType>::dv_reg_common4(
        const std::vector<RegexType> &regex_, const int len,
        const std::function<bool(size_t, size_t)> &compare) const {

    if (this->m_size == 0) return ZDataView{*this, 0, 0};;
    const auto& thisPtr = ItemPtr.get();

    size_t startIndex = this->m_size;
    size_t endIndex = 0;

    for (size_t i = 0; i < this->m_size; ++i) {
        const StringType &field_value = ThisType::template getField<field>(thisPtr[i]);
        if (compare(field_value.size(), len)) {
            for (const auto &reg: regex_) {
                if (matches_regex(field_value, reg)) {
                    if (startIndex == this->m_size) {
                        startIndex = i;
                    }
                    endIndex = i + 1;
                    break;
                }
            }
            if (startIndex != this->m_size && endIndex > 0) {
                return ZDataView{*this, startIndex, endIndex};
            }
        } else {
            if (startIndex != this->m_size && endIndex > 0) {
                return ZDataView{*this, startIndex, endIndex};
            }
            startIndex = this->m_size;
            endIndex = 0;
        }
    }

    if (startIndex != this->m_size && endIndex > 0) {
        return ZDataView{*this, startIndex, endIndex};
    }

    return ZDataView{*this, 0, 0};
}


template<typename StringType>
template<NDFrame::Field field>
NDFrame::ZDataView<StringType> NDFrame::ZDataFrame<StringType>::dv_reg_common3(
        const std::vector<RegexType> &regex_,
        const std::function<bool(const ItemType &)> &condition
) const {
    if (this->m_size == 0) return ZDataView<StringType>{*this, 0, 0};

    size_t startIndex = this->m_size;
    size_t endIndex = 0;
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        if (condition(thisPtr[i])) {
            const StringType &field_value = ThisType::template getField<field>(thisPtr[i]);
            for (const auto &reg: regex_) {
                if (matches_regex(field_value, reg)) {
                    if (startIndex == this->m_size) {
                        startIndex = i;
                    }
                    endIndex = i + 1;
                    break;
                }
            }
            if (startIndex != this->m_size && endIndex > 0) {
                return ZDataView<StringType>{*this, startIndex, endIndex};
            }
        } else {
            if (startIndex != this->m_size && endIndex > 0) {
                return ZDataView<StringType>{*this, startIndex, endIndex};
            }
            startIndex = this->m_size;
            endIndex = 0;
        }
    }

    if (startIndex != this->m_size && endIndex > 0) {
        return ZDataView<StringType>{*this, startIndex, endIndex};
    }

    return ZDataView<StringType>{*this, 0, 0};
}


template<typename StringType>
template<typename ConditionInt>
NDFrame::ZDataView<StringType> NDFrame::ZDataFrame<StringType>::DV_loc(ConditionInt conditionInt) const {
    if (this->m_size == 0) return ZDataView<StringType>{*this, 0, 0};

    size_t startIndex = this->m_size;
    size_t endIndex = 0;
    const auto& thisPtr = ItemPtr.get();

    for (size_t i = 0; i < this->m_size; ++i) {
        if (conditionInt(thisPtr[i])) {
            if (startIndex == this->m_size) {
                startIndex = i;
            }
            endIndex = i + 1;
        } else {
            if (startIndex != this->m_size && endIndex > 0) {
                return ZDataView<StringType>{*this, startIndex, endIndex};
            }
            startIndex = this->m_size;
            endIndex = 0;
        }
    }

    if (startIndex != this->m_size && endIndex > 0) {
        return ZDataView<StringType>{*this, startIndex, endIndex};
    }

    return ZDataView<StringType>{*this, 0, 0};
}

template class NDFrame::ZDataFrame<std::string>;
template class NDFrame::ZDataFrame<std::wstring>;
